package com.opensource.lzx.handler;

import com.opensource.lzx.proto.OperationType;
import com.opensource.lzx.proto.RequestContext;
import com.opensource.lzx.proto.ServiceResponse;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;

import java.util.concurrent.atomic.AtomicInteger;

public class HeartBeatHandler extends ChannelInboundHandlerAdapter {
    private static final AtomicInteger count = new AtomicInteger(0);

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        RequestContext context = (RequestContext) msg;
        if (context.getRequest().getType().getNumber() == OperationType.HEARTBEAT_REQUEST.getNumber()) {

            ServiceResponse.Builder builder = ServiceResponse.newBuilder();
            builder.setMessage("Request handler success");
            builder.setCode(200);
            builder.setRequestId(context.getRequest().getRequestId());
            builder.setType(OperationType.HEARTBEAT_RESPONSE);

            RequestContext.Builder response = RequestContext.newBuilder();
            response.setResponse(builder.build());

            ctx.channel().writeAndFlush(response.build());
        } else {
            super.channelRead(ctx, msg);
        }
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event == IdleStateEvent.ALL_IDLE_STATE_EVENT) {
                count.getAndIncrement();
                System.out.println("客户端：" + ctx.channel().remoteAddress() + " 服务器状态出现错误");
                if (count.get() > 2) {
                    ctx.channel().close();
                }
            } else {
                super.userEventTriggered(ctx, evt);
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();

        ctx.channel().close();
    }
}
